<template>
	<div class="editor" v-loading="loading" element-loading-text="生成中...">
		<div class="header">
			<div class="editor-header-title">
				<div class="home-btn" @click="goHome"></div>
				<span>{{ docsEntity?.title }}</span>
			</div>
			<div class="editor-header-right">
				<el-button size="small" type="primary" @click="autoSave">保存</el-button>
			</div>
		</div>
		<EditorPlus ref="editorRef" :llm_url="llm_url" :llm_key="llm_key" :llm_model="llm_model"
			:export_api="export_api" :import_api="import_api" @change="onchange" />
	</div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { EditorPlus } from '@/components/editor/index.ts'
import { ElMessage } from 'element-plus'
import { marked } from 'marked';
import { proposalApi } from '@/api/proposal.ts'
import { templateApi } from '@/api/template.ts'
import { replyMessage } from '@/utils/model.ts'
import { genHtml2Png } from '@/utils/html2Img'

const route = useRoute()
const llm_url = import.meta.env.VITE_LLM_URL as string;
const llm_key = import.meta.env.VITE_LLM_KEY as string;
const llm_model = import.meta.env.VITE_LLM_MODEL as string;
const export_api = '/api/export'
const import_api = '/api/import'

const loading = ref(false)

const editorRef = ref<any>(null)
const docsEntity = ref<any>()
const getDetail = async (id: number | string) => {
	try {
		loading.value = true
		const res = await proposalApi.getDocsDetail(id);
		if (res) {
			docsEntity.value = res;
			// 判断是否使用模板
			if (docsEntity.value.templateId && !docsEntity.value.content) {
				const templateRes = await templateApi.getTempDetail(docsEntity.value.templateId);
				const query = `${docsEntity.value.query} \n 请严格按照模板内容生成内容，模板内容如下：\n ${templateRes?.content}`
				await genDocsByLlm(docsEntity.value.prompt, query)
				autoSave()
			} else if (!docsEntity.value.content && docsEntity.value.query && docsEntity.value.prompt) {
				await genDocsByLlm(docsEntity.value.prompt, docsEntity.value.query)
				autoSave()
			} else {
				await editorRef.value.setEditorContent(marked.parse(docsEntity.value.content || ''));
				loading.value = false;
			}
		} else {
			loading.value = false
			editorRef.value.setEditorContent('');
			console.error('获取详情失败:');
		}
	} catch (error) {
		loading.value = false
		console.error('请求错误:', error);
	};
}

const saveTimer = ref<NodeJS.Timeout | null>(null);
const isSaving = ref(false);
const onchange = async () => {
	if (isSaving.value) return;

	if (saveTimer.value) {
		clearTimeout(saveTimer.value);
	}

	isSaving.value = true;
	saveTimer.value = setTimeout(async () => {
		await autoSave();
		isSaving.value = false;
	}, 10000);
}

// 调用大模型接口生成文档内容
const genDocsByLlm = async (prompt: string, query: string) => {
    try {
        const response = await replyMessage({
            prompt: prompt,
            query: query,
        });
        if (!response.ok) {
            throw new Error('网络响应异常');
        }

        const reader = response.body?.getReader();
        const decoder = new TextDecoder();
        let buffer = '';
        let fullContent = '';

        if (!reader) {
            throw new Error('响应体不可读');
        }

        while (true) {
            const { done, value } = await reader.read();
            if (done) break;

            buffer += decoder.decode(value);
            const lines = buffer.split('\n');
            buffer = lines.pop() ?? '';

            for (const line of lines) {
                if (line.startsWith('data:') && line !== 'data: [DONE]') {
                    try {
                        const data = JSON.parse(line.substring(5));
                        fullContent += data.result.output.text || '';
                    } catch (e) {
                        console.error('解析错误:', e);
                    }
                }
            }
        }

		fullContent = marked.parse(fullContent)
		loading.value = false
        
        // 第三步：逐字显示内容
        // for (let i = 0; i < fullContent.length; i++) {
        //     const parsedHtml = fullContent[i];
        //     editorRef.value.setEditorContent(parsedHtml);
        //     editorRef.value.scrollToBottom();
        //     await new Promise(resolve => setTimeout(resolve, 20));
        // }
		editorRef.value.setEditorContent(fullContent);
        editorRef.value.scrollToBottom();
    } catch (error) {
        console.error('请求失败:', error);
        ElMessage.error('文档生成失败');
    }
}

const autoSave = async () => {
	if (!docsEntity.value) {
		return;
	}
	try {
		let base64Str = await genHtml2Png(document.querySelector('.aie-container-main'))

		docsEntity.value.content = editorRef.value.getEditorContent('markdown');
		docsEntity.value.words = editorRef.value.getEditorWords();
		docsEntity.value.cover = base64Str
		await proposalApi.updateDocs(docsEntity.value.id, docsEntity.value);
		showSaveTip();
	} catch (error) {
		console.error('自动保存失败:', error);
	}
}


const showSaveTip = () => {
	const appDiv = document.querySelector('#app')
	if (!appDiv) return;
	const saveTip = document.createElement('div')
	saveTip.textContent = '自动保存成功';
	saveTip.style.position = 'fixed';
	saveTip.style.bottom = '-12px';
	saveTip.style.right = '0';
	saveTip.style.transform = 'translate(-50%, -50%)';
	saveTip.style.color = '#67c23a';
	saveTip.style.fontSize = '14px';
	saveTip.style.zIndex = '9';
	saveTip.style.transition = 'opacity 0.5s';
	appDiv.appendChild(saveTip);

	// 2秒后淡出并移除
	setTimeout(() => {
		saveTip.style.opacity = '0';
		setTimeout(() => {
			appDiv.removeChild(saveTip);
		}, 500);
	}, 2000);
}

onMounted(() => {
	const { id } = route.params as { id: number | string };
	if (id) {
		getDetail(id)
	}
	window.addEventListener('beforeunload', autoSave);
});

// 组件卸载时清除定时器
onUnmounted(() => {
	autoSave()
	window.removeEventListener('beforeunload', autoSave);
})

const goHome = () => {
	window.close();
}
</script>
<style lang="less" scoped>
.header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	height: 45px;
	padding: 0 20px;
	border-bottom: 1px solid #ebeef5;
}

.editor-header-title {
	display: flex;
	align-items: center;
	background-repeat: no-repeat;
	flex-shrink: 0;
	font-weight: 400;
	font-size: 20px;

	.home-btn {
		position: relative;
		display: inline-block;
		width: 26px;
		height: 26px;
		margin-right: 40px;
		background: url('@/assets/img/icon-home.png') no-repeat center / contain;
		cursor: pointer;
		transition: background-color 0.3s;

		&:hover {
			opacity: 0.8;
		}

		&:after {
			content: '';
			position: absolute;
			top: 58%;
			right: -20px;
			width: 1px;
			height: 20px;
			background-color: rgb(229, 231, 235);
			transform: translate(0, -50%);
		}
	}

	span {
		transform: translateY(1px);
	}
}
</style>